package com.ben.chatroom.common.codec;

import com.ben.chatroom.common.ProInstant;
import com.ben.chatroom.common.entity.ProtoMsg;
import com.ben.chatroom.common.exception.BusinessException;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

/**
 * @author huangyijun
 */
public class ProtobufDecoder extends ByteToMessageDecoder {


  @Override
  protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> list) throws Exception {
    in.markReaderIndex();

    if(in.readableBytes() < 0) {
      return;
    }

    short magic = in.readShort();
    if(magic != ProInstant.MAGIC_CODE) {
      throw new BusinessException("通信魔数不对:" + channelHandlerContext.channel().remoteAddress());
    }

    short version = in.readShort();

    if(version != ProInstant.VERSION_CODE) {
      throw new BusinessException("解码版本不对,请升级到最新版本");
    }

    int length = in.readInt();

    if(length < 0) {
      //非法数据
      channelHandlerContext.close();
    }

    if(length > in.readableBytes()) {
      in.resetReaderIndex();
      return;
    }

    byte[] arr;

    if(in.hasArray()) {
      ByteBuf slice = in.slice(in.readerIndex(), length);
      arr = slice.array();
      in.retain();
    }
    else {
      arr = new byte[length];
      in.readBytes(arr, 0, length);
    }

    ProtoMsg.Message message = ProtoMsg.Message.parseFrom(arr);
    if(in.hasArray()) {
      in.release();
    }

    if(message != null) {
      list.add(message);
    }

  }
}
